package com.dituhui.tool.gis;

import com.dituhui.tool.util.StringUtil;

/**
 * 点对象
 * 
 * @author liweigu
 * 
 */
public class Point {
	// 经纬度坐标的上限值
	private static final int MAX_GPS_DEGREE = 360;
	// 用于计算距离
	private static double EARTH_RADIUS = 6378137;

	/**
	 * X坐标
	 */
	public double x;
	/**
	 * Y坐标
	 */
	public double y;

	/**
	 * 构造函数
	 * 
	 */
	public Point() {
	}

	/**
	 * 构造函数
	 * 
	 * @param x X坐标
	 * @param y Y坐标
	 */
	public Point(double x, double y) {
		this.x = x;
		this.y = y;
	}

	/**
	 * 构造函数
	 * 
	 * @param point 点
	 */
	public Point(Point point) {
		this.x = point.x;
		this.y = point.y;
	}

	/**
	 * 获取X坐标
	 * 
	 * @return X坐标
	 */
	public double getX() {
		return this.x;
	}

	/**
	 * 获取Y坐标
	 * 
	 * @return Y坐标
	 */
	public double getY() {
		return this.y;
	}

	/**
	 * 设置X坐标
	 * 
	 * @return X坐标
	 */
	public void setX(double x) {
		this.x = x;
	}

	/**
	 * 设置Y坐标
	 * 
	 * @return Y坐标
	 */
	public void setY(double y) {
		this.y = y;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Point) {
			Point point = (Point) obj;
			if (point != null) {
				if (this.x == point.x && this.y == point.y) {
					return true;
				}
			}
		}
		return false;
	}

	@Override
	/**
	 * 转换为字符串。字符串内容为：x1,y1。摩卡托坐标，保留小数点后1位；经纬度坐标，保留小数点后6位。
	 */
	public String toString() {
		String strX, strY;
		if (this.x > MAX_GPS_DEGREE) {
			// 摩卡托坐标，保留小数点后1位
			strX = StringUtil.formatDouble(this.x, StringUtil.OneFractionFormat);
			strY = StringUtil.formatDouble(this.y, StringUtil.OneFractionFormat);
		} else {
			// 经纬度坐标，保留小数点后6位
			strX = StringUtil.formatDouble(this.x, StringUtil.SixFractionFormat);
			strY = StringUtil.formatDouble(this.y, StringUtil.SixFractionFormat);
		}
		StringBuilder stringBuilder = new StringBuilder(strX);
		stringBuilder.append(StringUtil.COMMA);
		stringBuilder.append(strY);
		return stringBuilder.toString();
	}

	// private double distanceTo2(Point point) {
	// double distance = -1;
	//
	// if (point != null && point.getX() > 0 && point.getY() > 0 && this.getX() > 0 && this.getY() > 0) {
	// Point startPoint = this;
	// Point endPoint = point;
	// if (startPoint.getX() < MAX_GPS_DEGREE && startPoint.getY() < MAX_GPS_DEGREE) {
	// // 如果是经纬度坐标，则转换为摩卡托。
	// // 先复制GPSPoint，避免改变原来对象的值。
	// startPoint = new Point(startPoint);
	// startPoint = CoordConverter.lngLatToMercator(startPoint);
	// }
	// if (endPoint.getX() < MAX_GPS_DEGREE && endPoint.getY() < MAX_GPS_DEGREE) {
	// // 如果是经纬度坐标，则转换为摩卡托。
	// // 先复制GPSPoint，避免改变原来对象的值。
	// endPoint = new Point(endPoint);
	// endPoint = CoordConverter.lngLatToMercator(endPoint);
	// }
	// double deltaX = startPoint.getX() - endPoint.getX();
	// double deltaY = startPoint.getY() - endPoint.getY();
	// double mercatorDistance = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
	// distance = mercatorDistance;
	// }
	//
	// return distance;
	// }

	private static double rad(double d) {
		return d * Math.PI / 180.0;
	}

	/**
	 * 计算两点的距离
	 * 
	 * @param point 另一个点
	 * @return 距离，单位是米
	 */
	public double distanceTo(Point point) {
		Point startPoint = this;
		Point endPoint = point;
		if (startPoint.getX() > MAX_GPS_DEGREE && startPoint.getY() > MAX_GPS_DEGREE) {
			// 如果是摩卡托坐标，则转换为经纬度。
			startPoint = CoordConverter.mercatorToLngLat(startPoint);
		}
		if (endPoint.getX() > MAX_GPS_DEGREE && endPoint.getY() > MAX_GPS_DEGREE) {
			// 如果是摩卡托坐标，则转换为经纬度。
			endPoint = CoordConverter.mercatorToLngLat(endPoint);
		}

		double lng1 = startPoint.getX();
		double lat1 = startPoint.getY();
		double lng2 = endPoint.getX();
		double lat2 = endPoint.getY();

		double radLat1 = rad(lat1);
		double radLat2 = rad(lat2);
		double a = radLat1 - radLat2;
		double b = rad(lng1) - rad(lng2);
		double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
		s = s * EARTH_RADIUS;
		// 精确到小数点后一位
		s = Math.round(s * 10) / 10.0;
		return s;
	}

}
